import aiofiles.base
from server import config
import os
# import pickle
import aiofiles
import asyncio
import shutil
from server.userobj import User

# 存储api

# 已弃用
# class Storage():
#     def __init__(self, plugid):
#         self.data = None
#         self.plugid = plugid
#         if (os.path.exists("config"+os.sep+"session"+os.sep+config.read("account")["username"]+os.sep+self.plugid+".pickle")):
#             with open("config"+os.sep+"session"+os.sep+config.read("account")["username"]+os.sep+self.plugid+".pickle", "rb") as file:
#                 self.data = pickle.load(file)
#         self.need_write = False

#     async def set(self, obj):
#         self.data = obj
#         self.need_write = True

#     async def get(self):
#         return self.data

#     async def write_file(self):
#         if (self.need_write == True):
#             if (not os.path.exists("config"+os.sep+"session"+os.sep+config.read("account")["username"])):
#                 os.makedirs("config"+os.sep+"session" +
#                             config.read("account")["username"])
#             async with aiofiles.open("config"+os.sep+"session"+os.sep+config.read("account")["username"]+os.sep+self.plugid+".pickle", "wb") as file:
#                 await file.write(pickle.dumps(self.data))
#             self.need_write = False


class FileStorageItem():
    def __init__(self, plugid, path):
        self.path = path
        self.plugid = plugid

    async def listdir(self) -> list[str]:
        return await asyncio.to_thread(lambda: os.listdir(self.path))

    def open(self, path, mode: str = "r", encoding: None | str = None) -> aiofiles.base.AiofilesContextManager:
        return aiofiles.open(            # type: ignore
            file=self.path+os.sep+path,  # type: ignore
            mode=mode,                   # type: ignore
            encoding=encoding)           # type: ignore

    async def exists(self, path):
        return await asyncio.to_thread(lambda: os.path.exists(self.path+os.sep+path))

    async def mkdir(self, path):
        return await asyncio.to_thread(lambda: os.mkdir(self.path+os.sep+path))

    async def remove(self, path):
        if (await self.exists(path)):
            if (await self.isdir(path)):
                return await asyncio.to_thread(lambda: shutil.rmtree(self.path+os.sep+path))
            else:
                return await asyncio.to_thread(lambda: os.remove(self.path+os.sep+path))

    rmdir = remove
    rmtree = remove

    async def isdir(self, path):
        return await asyncio.to_thread(lambda: os.path.isdir(self.path+os.sep+path))

    async def isfile(self, path):
        return await asyncio.to_thread(lambda: os.path.isfile(self.path+os.sep+path))

    def __div__(self, path) -> str:
        return self.path+os.sep+path

    def __add__(self, path) -> str:
        return self.path+os.sep+path


class FileStorage():
    def __init__(self, plugid):
        self.plugid = plugid
        self.storageitems = {}
        for k in os.listdir("config"+os.sep+"session"):
            if (not os.path.exists("config"+os.sep+"session"+os.sep+k+os.sep+self.plugid+".storage")):
                continue
            for i in os.listdir("config"+os.sep+"session"+os.sep+k+os.sep+self.plugid+".storage"):
                self.storageitems[k] = {}
                if (i.split(".")[-1] == 'temp'):
                    shutil.rmtree("config"+os.sep+"session"+os.sep +
                                  k+os.sep+self.plugid+".storage"+os.sep+i)

    async def load(self, user: User, storage_name: str, create_everytime: bool = False) -> FileStorageItem:
        save_ext = ".save"
        if (create_everytime == True):
            save_ext = ".temp"
        if (user.username not in self.storageitems):
            self.storageitems[user.username] = {}
        if (storage_name not in self.storageitems):
            await asyncio.to_thread(lambda: os.makedirs("config"+os.sep+"session"+os.sep+user.username+os.sep+self.plugid+".storage"+os.sep+storage_name+save_ext, exist_ok=True))
            self.storageitems[user.username][storage_name] = FileStorageItem(
                self.plugid, "config"+os.sep+"session"+os.sep+user.username+os.sep+self.plugid+".storage"+os.sep+storage_name+save_ext)
        return self.storageitems[user.username][storage_name]
